<template>
  <el-container class="home-container">
    <el-header>
      <div class="header-left">欢迎 {{ user.nickname }} 进入音乐管理系统</div>
      <div class="header-right">
        <el-dropdown @command="handleCommand">
          <span class="el-dropdown-link">
            <el-icon><Setting/></el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="changePassword">更改密码</el-dropdown-item>
              <el-dropdown-item command="logout">退出</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </el-header>
    <el-container>
      <el-aside>
        <el-menu
            active-text-color="#409EFF"
            background-color="#333744"
            :default-active="activePath"
            ::unique-opened="true"
            text-color="#fff"
            router>
          <!--一级菜单-->
          <el-sub-menu :index="menus.psId+''" v-for="menus in user.authorVOS" :key="menus.psId">
            <template #title><span>{{ menus.psCname }}</span></template>
            <!--二级菜单-->
            <el-menu-item :index="'/'+menu.psPath"
                          v-for="menu in menus.children"
                          :key="menu.psId"
                          @click="saveNavState('/' + menu.psPath)">
              {{ menu.psCname }}
            </el-menu-item>
          </el-sub-menu>
        </el-menu>
      </el-aside>
      <el-main>
       <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>

  <!--更改密码对话框-->
  <el-dialog v-model="dialogVisible" title="更新用户密码" width="30%" :before-close="handleClosed">
    <el-form :rules="changePasswordRules" :model="changePassword" ref="changePasswordFormRef" status-icon>
      <el-form-item prop="oldPassword" label="原密码">
        <el-input v-model="changePassword.oldPassword"
                  class="w-50 m-2"
                  type="password"
                  placeholder="请输入6~13旧密码"
                  minlength="6"
                  maxlength="13"
                  size="large"
                  autocomplete="off"
                  show-password clearable validate-event>
        </el-input>
      </el-form-item>

      <el-form-item prop="newPassword" label="新密码">
        <el-input v-model="changePassword.newPassword"
                  class="w-50 m-2"
                  type="password"
                  placeholder="请输入6~13位新密码"
                  minlength="6"
                  maxlength="13"
                  size="large"
                  autocomplete="off"
                  show-password clearable validate-event>
        </el-input>
      </el-form-item>

      <el-form-item prop="reenterPassword" label="新密码">
        <el-input v-model="changePassword.reenterPassword"
                  class="w-50 m-2"
                  type="password"
                  placeholder="请再次输入新密码"
                  minlength="6"
                  maxlength="13"
                  size="large"
                  autocomplete="off"
                  show-password clearable validate-event>
        </el-input>
      </el-form-item>
    </el-form>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeDialog">取消</el-button>
        <el-button type="primary" @click="submitForm(changePasswordFormRef)">提交</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
  //挂载后需要从后台获取当前用户的权限数据，进行页面的加载
import {Setting} from "@element-plus/icons-vue";
import axios from "axios";
import router from "@/router/index.js";
import { getCurrentInstance, reactive,ref,onMounted } from "vue";
const msg = getCurrentInstance().appContext.config.globalProperties.$message

//更改密码表单ref
const changePasswordFormRef=ref(null);

//对话框是否显示
const dialogVisible=ref(false);

//更改密码对象
const changePassword=reactive({
  id: '',
  oldPassword: '',
  newPassword: '',
  reenterPassword: ''
})

//关闭更改密码对话框
const handleClosed=()=>{
  closeDialog();
}

//查询的用户和权限信息
let user=ref({});

//取消
function closeDialog(){
  //重置表单
  changePasswordFormRef.value.resetFields();
  dialogVisible.value=false;
}

//自定义校验规则
//新旧密码不能一致
const checkNewPassword = (rule, value, callback) => {
  // 新密码不能与旧密码一样
  if(changePassword.newPassword !== changePassword.oldPassword){
    return callback()
  }
  callback(new Error('新密码不能与旧密码一样，请重新输入新密码!'))
}

//校测密码的强度
const checkPasswordStrength = (rule, value, callback) => {
  /*
  * (?=.*\d):至少有一个数字
  * (?=.*[a-z]):至少有一个小写字母
  * (?=.*[A-Z]):至少有一个大写字母
  * (?=.*[~!@#$%^&+=]):至少有一个特殊字符(这里列举了一些常见的特殊字符)
  * (?=\S+$):没有空白字符(这个要求可能是不必要的，除非你的需求中有特别强调)
  * .{6,13}:至少有6个字符长
  * */
  const reg=/(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[~!@#$%^&+=])(?=\S+$).{6,13}/
  // 新密码必须由a-zA-Z0-9~!@#$%^&+=等符号组成的6～13个字符
  if(changePassword.newPassword.match(reg)){
    return callback()
  }
  callback(new Error('密码必须包含数字，大小写字母以及(~!@#$%^&+=)括号中的任意一个字符'))
}

//再次输入的新密码必须与第一次输入的新密码一致
const checkPassword = (rule, value, callback) => {
  //两次输入的新密码必须一致
  if(changePassword.reenterPassword === changePassword.newPassword){
    return callback()
  }
  callback(new Error('两次密码不一致，请重新输入密码!'))
}

//密码校验规则
const changePasswordRules=reactive({
  oldPassword:[
      {
        required:true,
        message: '密码不能为空!',
        trigger: 'blur'
      },
      {
        min: 6,
        max: 13,
        message: '密码长度必须在6～13位',
        trigger: 'blur'
      }
    ],
  newPassword:[
    {
      required:true,
      message: '密码不能为空!',
      trigger: 'blur'
    },
    {
      min: 6,
      max: 13,
      message: '密码长度必须在6～13位',
      trigger: 'blur'
    },
    {
      validator:checkNewPassword,
      trigger: 'blur'
    },
    {
      validator:checkPasswordStrength,
      trigger: 'blur'
    }
  ],
  reenterPassword:[
    {
      required:true,
      message: '密码不能为空!',
      trigger: 'blur'
    },
    {
      min: 6,
      max: 13,
      message: '密码长度必须在6～13位',
      trigger: 'blur'
    },
    {
      validator:checkPassword,
      trigger: 'blur'
    }
  ]
  })

//处理退出和更改密码
function handleCommand(eventName){
  if(eventName==="changePassword"){
    //打开更新密码对话框
    dialogVisible.value=true;
  }else {
    //退出处理逻辑
    const options = {
      url: '/user/logout',
      method: 'post',
      headers: {'Content-Type': 'application/json'}
    };
    axios(options).then(res => {
      let mg = res.data;
      if (mg.meta.code === 200) {
        //如果退出成功，将token清除，并跳转页面
        msg.success(mg.meta.msg);
        sessionStorage.removeItem("token");
        router.push("/login");
      } else {
        msg.error(mg.meta.msg);
        sessionStorage.removeItem("token");
        router.push("/login");
      }
    }).catch(err => {
      msg.error(err);
    })
  }
}

//提交表单
function submitForm(formRef){
  formRef.validate(async validate =>{
    if (!validate) return
    //更改密码的数据
    const options = {
      url: '/user/updateUserPassword',
      method: 'post',
      data: {id:changePassword.id,oldPassword:changePassword.oldPassword,newPassword:changePassword.newPassword},
      headers: {'Content-Type': 'application/json'}
    };

    axios(options).then(res => {
      let mg = res.data;
      if (mg.meta.code === 200) {
        //更新密码成功
        msg.success(mg.meta.msg);
        //关闭更新密码对话框
        dialogVisible.value=false;
        sessionStorage.removeItem("token");
        router.push("/login");
      } else {
        //密码不对或者其他问题
        sessionStorage.removeItem("token");
        router.push("/login");
      }
    }).catch(err => {
      //网络异常啥的
      msg.error(err);
    })
  });
}

//长时间不活动，token过期了，要提示并且退出,解决异常--------------待完善

let activePath=ref();

function saveNavState (activeMenuPath) {
  sessionStorage.setItem('activePath', activeMenuPath)
  activePath.value = activeMenuPath
}

//获取用户的基本信息和所拥有的左侧菜单栏的权限信息
function getMenus(){
  const options = {
    //获取用户信息和权限信息
    url: '/user/selectMenus',
    method: 'GET',
    headers: {'Content-Type': 'application/json'}
  };

  axios(options).then(res => {
    let mg = res.data;
    if (mg.meta.code === 200) {
      //更新密码成功
      msg.success(mg.meta.msg);
      user.value=mg.data;
      changePassword.id=user.value.id;
    } else {
      //密码不对或者其他问题
      msg.error(mg.meta.msg);
      sessionStorage.removeItem("token");
      router.push("/login");
    }
  }).catch(err => {
    //网络异常啥的
    msg.error(err);
  })
}

onMounted(()=>{
  getMenus();
  activePath.value=sessionStorage.getItem("activePath");
});

</script>

<style scoped>

.home-container{
  height: 100vh;
}

.el-header{
  background-color: #373D41;
  font-size: 20px;
}

.header-left{
  display: flex;
  color: white;
  float: left;
  line-height: 50px;
  text-align: center;
}

.header-right{
  display: flex;
  float: right;
}

.el-dropdown{
  line-height: 50px;
}

:deep(.el-tooltip__trigger:focus-visible){
  outline:none;
}

.el-dropdown-link{
  cursor: pointer;
  color: white;
  align-items: center;
}

/*.container .el-container{
  width: 100%;
  height: 788px;
}*/

.el-aside{
  width: 120px;
  height: 100%;
  background-color: #333744;
}

.el-menu{
  border-right: none;
  font-size: 14px;
}

.el-menu-item{
  font-size: 12px;
}

.el-main{
  background-color: #EAEDF1;
}

.dialog-footer button:first-child{
  margin-right: 10px;
}

</style>
